<template>
  <!-- 继承属性 -->
  <ElTable ref="tableRef" v-loading="loading" v-bind="{ ...$attrs }">
    <ElTableColumn v-if="sortable" width="40">
      <div class="pr-3 sort-icon cursor-move">
        <SvgIcon name="drag" width="20px" height="28px" color="#C7C7C7" />
      </div>
    </ElTableColumn>
    <visibleSlots :vnode="showSlots" />
    <ElTableColumn v-if="allFieldList.length" class-name="table-setting" prop="system_setting" label="" width="20" align="center" fixed="right">
      <template #header>
        <div class="cursor-pointer" @click="handleSetting">
          <el-icon>
            <Setting />
          </el-icon>
        </div>
      </template>
    </ElTableColumn>
    <template v-if="$slots.empty" #empty>
      <slot name="empty" />
    </template>
  </ElTable>

  <Pagination
    v-if="pagination"
    layout="sizes, prev, pager, next, jumper"
    :page="page"
    :page-size="limit"
    :total="total"
    @size-change="onSizeChange"
    @current-change="onCurrentChange"
  />

  <el-dialog v-model="showFieldVisible" title="列表显示设置" width="660px">
    <div class="flex border-b pb-4" style="height: 350px">
      <div class="flex-1 flex flex-col overflow-y-auto">
        <div class="flex-none text-sm mb-3">
          <span class="text-[#182B50]">需显示的字段</span>
          <span class="text-[#182B5066]">（最多展示{{ MAX_SHOW_NUM }}个）</span>
        </div>
        <div class="flex-1 overflow-y-auto">
          <div class="el-checkbox-group">
            <template v-for="field in allFieldList" :key="field.field_key">
              <el-checkbox
                :disabled="fixedFields.includes(field.field_key) || (showFieldList.length === 1 && field.field_key === showFieldList[0].field_key)"
                :checked="Boolean(showFieldList.find((item) => item.field_key === field.field_key))"
                :value="field.field_key"
                @change="handleFieldChange($event, field)"
              >
                {{ field.field_name }}
              </el-checkbox>
            </template>
          </div>
        </div>
      </div>
      <div class="border-l mx-4" />
      <div class="flex-1 flex flex-col">
        <div class="flex-none text-sm mb-3">
          <span class="text-[#182B50]">显示顺序</span>
          <span class="text-[#182B5066]">（拖动分组调整分组顺序）</span>
        </div>
        <Sortable v-model="showFieldList" identity="id" class="flex-1 w-full flex flex-col gap-1 overflow-y-auto">
          <template #item="{ item }">
            <div class="flex-none h-8 flex items-center">
              <div class="pr-3 sort-icon cursor-move">
                <svg-icon name="drag" width="16px" height="32px" color="#a1a5af" />
              </div>
              <div class="flex-1 text-sm text-[#182B50] truncate">
                {{ item.field_name }}
              </div>
            </div>
          </template>
        </Sortable>
      </div>
    </div>

    <template #footer>
      <el-button size="large" type="default" @click="handleCancel">取消</el-button>
      <el-button v-debounce size="large" type="primary" @click="handleConfirm">保存</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref, useSlots, onUnmounted, watch, getCurrentInstance, computed } from 'vue'

import { Setting } from '@element-plus/icons-vue'
import { ElTableColumn } from 'element-plus'

import Sortable from 'sortablejs'
import Pagination from '@/components/Pagination/index.vue'
import createSlots from './create-slots'

const { proxy } = getCurrentInstance()
const tableData = computed(() => proxy.$attrs.data || [])
const props = withDefaults(
  defineProps<{
    type?: string
    page?: number
    limit?: number
    total?: number
    prefix?: string
    pagination?: boolean
    // 固定显示那几个字段
    fixedFields?: any[]
    hiddenProps?: any[]
    // 需要插入到那个后面
    insertIndex?: number
    loading?: boolean
    sortable?: boolean
  }>(),
  {
    type: '',
    page: 1,
    limit: 10,
    total: 0,
    prefix: '',
    fixedFields: () => [],
    hiddenProps: () => [],
    pagination: true,
    loading: false,
    sortable: false
  }
)

const emits = defineEmits<{
  (event: 'pageSizeChange', data: any): any
  (event: 'pageCurrentChange', data: any): any
  (event: 'sortableChange', data: any): any
  (event: 'update:data', data: any): any
}>()

const MAX_SHOW_NUM = 30

const tableRef = ref()

const slots = useSlots()

const showSlots = ref([])
const visibleSlots = createSlots({
  mountedCallFun: () => {},
  updatedCallFun: () => {},
  unmountedCallFun: () => {}
})

const showFieldVisible = ref(false)
const allFieldList = ref([])
const showFieldList = ref([])

const onSizeChange = (...args) => {
  emits('pageSizeChange', ...args)
}
const onCurrentChange = (...args) => {
  emits('pageCurrentChange', ...args)
}

const handleSetting = () => {
  showFieldVisible.value = true
}

const handleFieldChange = (check: boolean, item: any) => {
  if (check) showFieldList.value.push({ ...item })
  else showFieldList.value = showFieldList.value.filter((i) => i.id !== item.id)
}

const handleCancel = () => {
  showFieldVisible.value = false
}
const handleConfirm = async () => {
  if (/^user_memory_list/im.test(props.type)) {
  }
  ElMessage.success('已设置')
  showFieldVisible.value = false
}

let sortableInstance: any = null
const initSortable = () => {
  if (!props.sortable || !tableData.value.length) return
  const sortable_el = tableRef.value.$el.querySelector('.el-table__body tbody')
  sortableInstance = Sortable.create(sortable_el, {
    onStart: (event = {}) => {
      const { target, oldIndex } = event
      target.children[oldIndex].style.background = '#ECF5FF'
    },
    onEnd: async (event = {}) => {
      const { target, newIndex: targetIndex, oldIndex: originIndex } = event
      if (target.children && target.children[targetIndex]) target.children[targetIndex].style.background = 'transparent'
      if (targetIndex === originIndex) return
      const list = JSON.parse(JSON.stringify(tableData.value))
      const originData = list.splice(originIndex, 1)[0]
      list.splice(targetIndex, 0, originData)
      emits('update:data', [])
      await nextTick()
      emits('update:data', list)
      emits('sortableChange', { data: list, targetIndex, originIndex })
    }
  })
}
const destroySortable = () => {
  if (sortableInstance) {
    sortableInstance.destroy()
    sortableInstance = null
  }
}

onMounted(() => {
  nextTick(() => {
    if (/^user_memory_list/im.test(props.type)) {
    } else {
      const slotList = slots.default()
      showSlots.value = slotList
    }
  })
})
onUnmounted(() => {
  destroySortable()
})

watch(
  () => tableData.value,
  async () => {
    destroySortable()
    await nextTick()
    initSortable()
  },
  {
    deep: true,
    immediate: true
  }
)
defineExpose({
  toggleRowSelection(...args) {
    tableRef.value.toggleRowSelection(...args)
  },
  refresh: () => {
    // loadUserMemoryFieldList()
  }
})
</script>

<style>
.table-setting .cell {
  padding: 0 6px 0 0;
}
</style>

<style scoped>
::v-deep(.el-checkbox-group) {
  display: flex;
  flex-wrap: wrap;
}

::v-deep(.el-checkbox-group .el-checkbox) {
  flex: 0 0 50%;
  margin-right: 0;
  overflow: hidden;
}

::v-deep(.el-checkbox-group .el-checkbox__label) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
